<template>
  <div class="datetime-selector-container" ref="container">
    <input
      :value="displayValue"
      @click="toggleDropdown"
      type="text"
      :placeholder="placeholder"
      :class="['datetime-input', inputClass]"
      readonly
      ref="input"
    />
    <div class="datetime-input-icon">
      <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
        <circle cx="12" cy="12" r="10"/>
        <polyline points="12,6 12,12 16,14"/>
      </svg>
    </div>
    
    <Teleport to="body">
      <div v-if="showDropdown" class="datetime-dropdown" ref="dropdown" :style="dropdownStyle">
      <div class="datetime-picker-header">
        <div class="date-section">
          <label class="picker-label">日期</label>
          <input
            v-model="selectedDate"
            type="date"
            class="date-picker-input"
          />
        </div>
        <div class="time-section">
          <label class="picker-label">时间</label>
          <div class="time-columns">
            <div class="time-column">
              <div class="column-header">时</div>
              <div class="column-content">
                <div
                  v-for="hour in hours"
                  :key="`hour-${hour}`"
                  :class="['time-option', { active: selectedHour === hour }]"
                  @click="selectHour(hour)"
                >
                  {{ String(hour).padStart(2, '0') }}
                </div>
              </div>
            </div>
            
            <div class="time-column">
              <div class="column-header">分</div>
              <div class="column-content">
                <div
                  v-for="minute in minutes"
                  :key="`minute-${minute}`"
                  :class="['time-option', { active: selectedMinute === minute }]"
                  @click="selectMinute(minute)"
                >
                  {{ String(minute).padStart(2, '0') }}
                </div>
              </div>
            </div>
            
            <div class="time-column">
              <div class="column-header">秒</div>
              <div class="column-content">
                <div
                  v-for="second in seconds"
                  :key="`second-${second}`"
                  :class="['time-option', { active: selectedSecond === second }]"
                  @click="selectSecond(second)"
                >
                  {{ String(second).padStart(2, '0') }}
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
      
      <div class="datetime-actions">
        <button @click="clearDateTime" class="datetime-btn datetime-btn-clear">清空</button>
        <button @click="confirmDateTime" class="datetime-btn datetime-btn-confirm">确定</button>
      </div>
      </div>
    </Teleport>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, onUnmounted, watch } from 'vue'

interface Props {
  modelValue?: string
  placeholder?: string
  inputClass?: string
}

const props = withDefaults(defineProps<Props>(), {
  modelValue: '',
  placeholder: '选择日期时间',
  inputClass: ''
})

const emit = defineEmits<{
  (e: 'update:modelValue', value: string): void
  (e: 'change', value: string): void
}>()

const showDropdown = ref(false)
const dropdown = ref<HTMLElement>()
const container = ref<HTMLElement>()
const input = ref<HTMLElement>()
const dropdownStyle = ref<{ top: string; left: string; width: string }>({
  top: '0px',
  left: '0px',
  width: '320px'
})

const selectedDate = ref<string>('')
const selectedHour = ref<number>(0)
const selectedMinute = ref<number>(0)
const selectedSecond = ref<number>(0)

// 生成选项数组
const hours = computed(() => Array.from({ length: 24 }, (_, i) => i))
const minutes = computed(() => Array.from({ length: 60 }, (_, i) => i))
const seconds = computed(() => Array.from({ length: 60 }, (_, i) => i))

// 显示值
const displayValue = computed(() => {
  if (!props.modelValue) return ''
  // 如果值包含日期和时间，格式化为显示格式
  if (props.modelValue.includes(' ')) {
    return props.modelValue
  }
  // 如果值包含T，将T替换为空格
  if (props.modelValue.includes('T')) {
    return props.modelValue.replace('T', ' ')
  }
  return props.modelValue
})

// 解析日期时间字符串
const parseDateTimeString = (dateTimeStr: string) => {
  if (!dateTimeStr) return { date: '', hour: 0, minute: 0, second: 0 }
  
  let dateStr = ''
  let hour = 0
  let minute = 0
  let second = 0
  
  // 处理 "YYYY-MM-DD HH:mm:ss" 格式
  if (dateTimeStr.includes(' ')) {
    const parts = dateTimeStr.split(' ')
    dateStr = parts[0]
    if (parts[1]) {
      const timeParts = parts[1].split(':')
      hour = parseInt(timeParts[0]) || 0
      minute = parseInt(timeParts[1]) || 0
      second = parseInt(timeParts[2]) || 0
    }
  }
  // 处理 "YYYY-MM-DDTHH:mm:ss" 格式
  else if (dateTimeStr.includes('T')) {
    const parts = dateTimeStr.split('T')
    dateStr = parts[0]
    if (parts[1]) {
      const timeParts = parts[1].split(':')
      hour = parseInt(timeParts[0]) || 0
      minute = parseInt(timeParts[1]) || 0
      second = parseInt(timeParts[2]) || 0
    }
  }
  // 只有日期
  else if (dateTimeStr.includes('-')) {
    dateStr = dateTimeStr
  }
  
  return { date: dateStr, hour, minute, second }
}

// 格式化日期时间为 "YYYY-MM-DD HH:mm:ss" 格式
const formatDateTime = (date: string, hour: number, minute: number, second: number): string => {
  if (!date) return ''
  const timeStr = `${String(hour).padStart(2, '0')}:${String(minute).padStart(2, '0')}:${String(second).padStart(2, '0')}`
  return `${date} ${timeStr}`
}

// 监听modelValue变化
watch(() => props.modelValue, (newValue) => {
  if (newValue) {
    const { date, hour, minute, second } = parseDateTimeString(newValue)
    selectedDate.value = date
    selectedHour.value = hour
    selectedMinute.value = minute
    selectedSecond.value = second
  } else {
    selectedDate.value = ''
    selectedHour.value = 0
    selectedMinute.value = 0
    selectedSecond.value = 0
  }
}, { immediate: true })

const updateDropdownPosition = () => {
  if (!input.value) return
  
  const rect = input.value.getBoundingClientRect()
  const dropdownWidth = 320
  const dropdownHeight = 280 // 预估高度
  const spacing = 4
  
  let top = rect.bottom + window.scrollY + spacing
  let left = rect.left + window.scrollX
  
  // 如果下拉框超出屏幕底部，显示在输入框上方
  if (rect.bottom + dropdownHeight > window.innerHeight + window.scrollY) {
    top = rect.top + window.scrollY - dropdownHeight - spacing
  }
  
  // 如果下拉框超出屏幕右侧，调整位置
  if (rect.left + dropdownWidth > window.innerWidth + window.scrollX) {
    left = window.innerWidth + window.scrollX - dropdownWidth - 10
  }
  
  // 如果下拉框超出屏幕左侧，调整位置
  if (left < window.scrollX) {
    left = window.scrollX + 10
  }
  
  dropdownStyle.value = {
    top: `${top}px`,
    left: `${left}px`,
    width: `${Math.max(rect.width, dropdownWidth)}px`
  }
}

const toggleDropdown = () => {
  showDropdown.value = !showDropdown.value
  if (showDropdown.value) {
    updateDropdownPosition()
    setTimeout(() => {
      scrollToSelectedTime()
    }, 100)
  }
}

const selectHour = (hour: number) => {
  selectedHour.value = hour
}

const selectMinute = (minute: number) => {
  selectedMinute.value = minute
}

const selectSecond = (second: number) => {
  selectedSecond.value = second
}

const updateDateTime = () => {
  if (selectedDate.value) {
    const newValue = formatDateTime(selectedDate.value, selectedHour.value, selectedMinute.value, selectedSecond.value)
    emit('update:modelValue', newValue)
    emit('change', newValue)
  }
}

const clearDateTime = () => {
  selectedDate.value = ''
  selectedHour.value = 0
  selectedMinute.value = 0
  selectedSecond.value = 0
  emit('update:modelValue', '')
  emit('change', '')
  showDropdown.value = false
}

const confirmDateTime = () => {
  if (selectedDate.value) {
    updateDateTime()
  }
  showDropdown.value = false
}

// 滚动到选中的时间
const scrollToSelectedTime = () => {
  if (!dropdown.value) return
  
  const columns = dropdown.value.querySelectorAll('.column-content')
  const values = [selectedHour.value, selectedMinute.value, selectedSecond.value]
  
  columns.forEach((column, index) => {
    const activeOption = column.querySelector('.time-option.active') as HTMLElement
    if (activeOption) {
      activeOption.scrollIntoView({ behavior: 'smooth', block: 'center' })
    }
  })
}

// 点击外部关闭下拉框
const handleClickOutside = (event: Event) => {
  const target = event.target as Node
  
  if (dropdown.value && dropdown.value.contains(target)) {
    return
  }
  
  if (input.value && input.value.contains(target)) {
    return
  }
  
  if (container.value && container.value.contains(target)) {
    return
  }
  
  showDropdown.value = false
}

// 监听窗口滚动和调整大小，更新下拉框位置
const handleScroll = () => {
  if (showDropdown.value) {
    updateDropdownPosition()
  }
}

const handleResize = () => {
  if (showDropdown.value) {
    updateDropdownPosition()
  }
}

onMounted(() => {
  document.addEventListener('click', handleClickOutside)
  window.addEventListener('scroll', handleScroll, true)
  window.addEventListener('resize', handleResize)
})

onUnmounted(() => {
  document.removeEventListener('click', handleClickOutside)
  window.removeEventListener('scroll', handleScroll, true)
  window.removeEventListener('resize', handleResize)
})
</script>

<style scoped>
.datetime-selector-container {
  position: relative;
  width: 100%;
}

.datetime-input {
  width: 100%;
  padding: 4px 4px 4px 8px;
  border: 1px solid var(--input-border-color);
  border-radius: 4px;
  font-size: 13px;
  background: var(--input-background);
  color: var(--text-color);
  cursor: pointer;
  transition: all 0.2s;
}

.datetime-input:focus {
  outline: none;
  border-color: rgba(56, 189, 248, 0.5);
  box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.1);
}

.datetime-input:hover {
  border-color: var(--input-border-color);
}

.datetime-input-icon {
  position: absolute;
  right: 8px;
  top: 50%;
  transform: translateY(-50%);
  color: var(--text-color);
  pointer-events: none;
  opacity: 0.6;
}

.datetime-dropdown {
  position: fixed;
  background: var(--sub-plate-bg-color);
  border: 1px solid var(--modal-main-border-color);
  border-radius: 4px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  z-index: 1200;
  min-width: 320px;
}

.datetime-picker-header {
  padding: 12px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.date-section,
.time-section {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.picker-label {
  font-size: 12px;
  font-weight: 500;
  color: var(--text-color);
}

.date-picker-input {
  width: 100%;
  padding: 6px 8px;
  border: 1px solid var(--input-border-color);
  border-radius: 4px;
  font-size: 13px;
  background: var(--input-background);
  color: var(--text-color);
}

.time-columns {
  display: flex;
  max-height: 160px;
  border: 1px solid var(--input-border-color);
  border-radius: 4px;
  overflow: hidden;
}

.time-column {
  flex: 1;
  border-right: 1px solid var(--input-border-color);
}

.time-column:last-child {
  border-right: none;
}

.column-header {
  padding: 6px;
  background-color: rgba(249, 250, 251, 0.5);
  border-bottom: 1px solid var(--input-border-color);
  text-align: center;
  font-weight: 500;
  font-size: 12px;
  color: var(--text-color);
}

.column-content {
  max-height: 120px;
  overflow-y: auto;
}

.column-content::-webkit-scrollbar {
  width: 4px;
}

.column-content::-webkit-scrollbar-track {
  background-color: var(--webkit-track-color);
  border-radius: 4px;
}

.column-content::-webkit-scrollbar-thumb {
  background-color: var(--webkit-thumb-color);
  border-radius: 4px;
}

.column-content::-webkit-scrollbar-thumb:hover {
  background-color: var(--webkit-thumb-hover-color);
}

.time-option {
  padding: 4px 8px;
  cursor: pointer;
  text-align: center;
  font-size: 13px;
  transition: background-color 0.2s;
  color: var(--text-color);
}

.time-option:hover {
  background-color: var(--btn-hover-color);
}

.time-option.active {
  background-color: var(--btn-click-color);
  color: white;
  border: solid 1px;
}

.datetime-actions {
  display: flex;
  justify-content: space-between;
  padding: 8px 12px;
  border-top: 1px solid var(--modal-divide);
  gap: 8px;
}

.datetime-btn {
  flex: 1;
  padding: 6px 12px;
  border: 1px solid var(--input-border-color);
  border-radius: 4px;
  background: var(--sub-plate-bg-color);
  cursor: pointer;
  font-size: 13px;
  transition: all 0.2s;
  color: var(--text-color);
}

.datetime-btn-clear:hover {
  border-color: var(--text-color);
  background-color: var(--btn-hover-color);
}

.datetime-btn-confirm {
  background-color: var(--btn-click-color);
  color: white;
  border-color: var(--btn-click-color);
}

.datetime-btn-confirm:hover {
  background-color: var(--btn-hover-color);
  border-color: var(--btn-hover-color);
}
</style>

